package com.infindo.frame.data;

import java.util.Vector;

import android.content.Context;
import android.util.Log;
//import android.util.Log;
//import android.util.Log;

import com.google.android.apps.analytics.GoogleAnalyticsTracker;
import com.infindo.frame.data.net.CallbackListener;
import com.infindo.frame.data.net.ImageGet;
import com.infindo.frame.data.net.RequestFacebookPost;
import com.infindo.frame.data.net.RequestGet;
import com.infindo.frame.data.net.RequestGet2;
import com.infindo.frame.data.net.RequestNewsLetterPost;
import com.infindo.frame.data.net.RequestPost;
import com.infindo.frame.data.net.RequestTwitterPost;
//import com.infindo.onemalaysia.manager.Const;
import com.tiantian.app.manager.DataModel;

@SuppressWarnings("unchecked")
public class DataProcessor implements Runnable{
	
	private static DataProcessor instance = new DataProcessor();
	
	public static DataProcessor getInstance() {
		return instance;
	}
	public static final int survTime = 60000;
	
	private boolean isStop;
	private Vector requestQueue;
	private Vector cancelQueue;
	private Vector imageQueue;
	private Vector allQueue;
	private Vector mapQueue;

	private ThreadManager threadMan;

	private Thread thread;
	private DataProcTimer dataTimer;
	
	
	private  static  GoogleAnalyticsTracker tracker;
	public static GoogleAnalyticsTracker getTracker(Context context) {
		if(tracker == null){
	        tracker = GoogleAnalyticsTracker.getInstance();
	    	//#ifdef production
	      	//Production Server: 
	      	tracker.start("UA-30698062-1",5,context);
	      	//#elifdef development
//@	          //Development Server:
//@	        tracker.start("",5,context);
	      	//#endif
		}
		return tracker;
	}
	
 
	
	public DataProcTimer getDataTimer() {
		return dataTimer;
	}

	private int dataHandlerNo;

	private DataProcessor()
	{
		isStop=false;
		requestQueue  = new Vector();
		cancelQueue   = new Vector();
		imageQueue    = new Vector();
		allQueue     = new Vector();
		mapQueue      = new Vector();
		threadMan     = new ThreadManager();
		dataTimer     = new DataProcTimer();
		dataHandlerNo = 0;
		thread = new Thread(this);
		thread.start();
	}
	
	 public static void clearHandler(){
	 		getInstance().cancelHandler(DataModel.getRequestID());
			getInstance().cancelHandler(DataModel.getRequestImageID());
			getInstance().clearImageQueue();
			getInstance().clearAllQueue();
	}

	
	public void setStop()
	{
		isStop=true;
	}

	

	public void run()
	{
		while(!isStop)
		{
			while (requestQueue.size() == 0) 
			{
				try
				{
                     synchronized(this)
                     {
					    wait();
                     }
				}
				catch (InterruptedException interruptedexception)
				{
//					System.out.println("error in  -run");
				}
				if (isStop)
					break;  
			}
			if (isStop)
				break;
			if(requestQueue.size()>0)
			{
				DataHandler mHandler;
				mHandler = (DataHandler)requestQueue.elementAt(0);
				process(mHandler);
			}
			synchronized (this)
			{
				if(requestQueue.size()>0)
					requestQueue.removeElementAt(0);
			}
		}
	}
	

	private synchronized void startToProc(DataHandler requestHandler)
	{
		requestQueue.addElement(requestHandler);
		allQueue.add(requestHandler.getDataHandlerNo());
		notify();
	}
	
	
	public int reqProc(Context context,String url,String data,String type,CallbackListener listener)
	{
		dataHandlerNo++;
		DataHandler jsonHandler = new RequestPost(context,url,data,type,false,this,dataHandlerNo,listener);
		jsonHandler.setHandlerType(DataHandler.DataTypeJson);
		startToProc(jsonHandler);
		DataModel.setRequestID(dataHandlerNo);
		return dataHandlerNo;
	}
	
	public int reqGet(Context context,String url,String type,CallbackListener listener)
	{
		dataHandlerNo++;
		DataHandler jsonHandler = new RequestGet(context,url,type,0,false,this,dataHandlerNo,listener);
		jsonHandler.setHandlerType(DataHandler.DataTypeJson);
		startToProc(jsonHandler);
		DataModel.setRequestID(dataHandlerNo);
		return dataHandlerNo;
	}
	
 
	public int reqProcData(Context context,String url,String data,String type,CallbackListener listener)
	{
		dataHandlerNo++;
		DataHandler jsonHandler = new RequestPost(context,url,data,type,false,this,dataHandlerNo,listener);
		jsonHandler.setHandlerType(DataHandler.DataTypeJson);
		startToProc(jsonHandler);
		DataModel.setRequestID(dataHandlerNo);
		return dataHandlerNo;
	}
 
	public int imageProc(Context context,String url,String imageType,String type,CallbackListener listener,int position)
	{
		if(url==null)
			return 0;
		
		dataHandlerNo++;
//		Log.e("imageProcessor",position+":"+dataHandlerNo+":"+url);
		DataHandler jsonHandler = new ImageGet(context,url,position,type,this,dataHandlerNo,listener);
		jsonHandler.setHandlerType(DataHandler.DataTypeImage);
		startToProc(jsonHandler);
		if(imageType.equals("map")){
			addMapQueue(dataHandlerNo);
		}else{
			addImageQueue(dataHandlerNo);
		}
		DataModel.setRequestImageID(dataHandlerNo);
		return dataHandlerNo;
	}
	
 
	
	public void restartToProc(DataHandler requestHandler)
	{
		dataHandlerNo++;
		requestHandler.setHandlerNo(dataHandlerNo);
		startToProc(requestHandler);
	}
	
	//***********************************************************************************

	//***********************************************************************************
	
	public synchronized void addImageQueue(int handlerNo)
	{
		imageQueue.addElement(""+handlerNo);
	}
	
	public synchronized void addMapQueue(int handlerNo)
	{
		mapQueue.addElement(""+handlerNo);
	}
	
	public synchronized void clearImageQueue()
	{
		for(int i=0;i<imageQueue.size();i++)
		{
			cancelHandler(Integer.parseInt(""+imageQueue.elementAt(i)));
		}
		imageQueue.removeAllElements();
	}
	
	public synchronized void clearAllQueue()
	{
		for(int i=0;i<allQueue.size();i++)
		{
			cancelHandler(Integer.parseInt(""+allQueue.elementAt(i)));
		}
		allQueue.removeAllElements();
	}
	
	public synchronized void clearMapQueue()
	{
		for(int i=0;i<mapQueue.size();i++)
		{
			cancelHandler(Integer.parseInt(""+mapQueue.elementAt(i)));
		}
		mapQueue.removeAllElements();
	}
	
	public synchronized boolean cancelHandler(int cancelHandlerNo)
	{
//		Log.v("cancelHandler", "***************   "+cancelHandlerNo);
		cancelQueue.addElement(""+cancelHandlerNo);
		if(checkQueue(cancelHandlerNo))
		{
			return true;
		}
		else if(checkThreadProc(cancelHandlerNo))
		{
			return true;
		}
		else if(checkConnectQueue(cancelHandlerNo))
		{
			return true;
		}
		return false;
	}
	
	public synchronized boolean checkNoCancelQueue(int dataHandlerNo)
	{
		if(cancelQueue.size()>0)
		{
			for(int i=0;i<cancelQueue.size();i++)
			{
				if(cancelQueue.elementAt(i).equals(""+dataHandlerNo))
				{
					cancelQueue.removeElementAt(i);
					return false;
				}
			}
		}
		if(cancelQueue.size()>500)
			cancelQueue.removeAllElements();
		return true;
	}
	

	private boolean checkConnectQueue(int dataHandlerNo)
	{
		if(dataTimer.checkConnectQueue(dataHandlerNo))
		{
			return true;
		}
		return false;
	}
	
	private boolean checkThreadProc(int dataHandlerNo)
	{
		if(threadMan.workerCancelHandler(dataHandlerNo))
		{
			return true;
		}
		return false;
	}
	
	private synchronized boolean checkQueue(int dataHandlerNo)
	{
		for(int i=0;i<requestQueue.size();i++)
		{
			DataHandler mHandler;
			mHandler = (DataHandler)requestQueue.elementAt(i);
			if(mHandler.getDataHandlerNo()==dataHandlerNo)
			{
				requestQueue.removeElementAt(i);
				return true;
			}
		}
	    return false;
	}
	
 
	
	private void process(DataHandler handler)
	{
		switch(handler.getHandlerType())
		{
		case DataHandler.DataTypeJson:
 
			threadMan.netProcess(handler);
			break;
		case DataHandler.DataTypeImage:
		    threadMan.netProcess(handler);
			break;
		case DataHandler.DataTypeByte:
			threadMan.netProcess(handler);
			break;
		case DataHandler.DataTypeInSt:
			threadMan.netProcess(handler);
			break;
		default:
			break;
		}
	}

}
